<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script>
  function BinaryTree() {
    function Node(key) {
      this.key = key;
      this.left = null;
      this.right = null;
    }


    let root = null;
    const insertNode = function (node, newNode) {
      if (newNode.key < node.key) {
        if (node.left === null) {
          node.left = newNode;
        } else {
          insertNode(node.left, newNode)
        }
      } else {
        if (node.right === null) {
          node.right = newNode;
        } else {
          insertNode(node.right, newNode)
        }
      }
    };
    this.insert = function (key) {
      const newNode = new Node(key);
      if (root === null) {
        root = newNode
      } else {
        insertNode(root, newNode)
      }
    };
    const inOrderTraverseNode = function (node, callback) {
      if (node !== null) {
        inOrderTraverseNode(node.left, callback);
        callback(node.key);
        inOrderTraverseNode(node.right, callback)
      }
    };
    this.inOrderTraverse = function (callback) {
      inOrderTraverseNode(root, callback);
    }
    const prevOrderTraverseNode = function (node, callback) {
      if (node !== null) {
        callback(node)
        prevOrderTraverseNode(node.left, callback)
        prevOrderTraverseNode(node.right, callback)
      }
    };
    this.prevOrderTraverse = function (callback) {
      prevOrderTraverseNode(root, callback)
    };
    const postOrderTraverseNode = function (node, callback) {
      if (node !== null) {
        postOrderTraverseNode(node.left, callback);
        postOrderTraverseNode(node.right, callback);
        callback(node.key)
      }
    }
    this.postOrderTraverse = function (callback) {
      postOrderTraverseNode(root, callback)
    }
    const minNode = function (node) {
      if (node) {
        while (node.left !== null) {
          node = node.left
        }
        return node.key
      }
      return null
    }
    this.min = function () {
      return minNode(root);
    }
    const maxNode = function (node) {
      if (node) {
        while (node.right !== null) {
          node = node.right
        }
        return node.key
      }
      return null
    }
    this.max = function () {
      return maxNode(root)
    }
    const searchNode = function (node, key) {
      if (node === null) {
        return false;
      }
      if (key < node.key) {
        return searchNode(node.left, key)
      } else if (key > node.key) {
        return searchNode(node.right)
      } else {
        return true
      }
    }
    this.search = function (key) {
      return searchNode(root, key)
    }
    const removeNode = function (node, key) {
      if (node === null) {
        return null
      }
      if (key < node.key) {
        node.left = removeNode(node.left, key)
        return node
      } else if (key > node.key) {
        node.right = removeNode(node.right, key)
        return node
      } else {
        if (node.left === null && node.right === null) {
          node = null
          return node
        }
        if (node.left === null) {
          node = node.right
          return node
        } else if (node.right === null) {
          node = node.left
          return node
        }
      }
    }
    this.remove = function (key) {
      return removeNode(root, key)
    }
  }

  const nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
  const binaryTree = new BinaryTree();
  nodes.forEach(item => {
    binaryTree.insert(item)
  });
  const callback = function (key) {
    console.log(key);
  };
  binaryTree.inOrderTraverse(callback);
</script>
</body>
</html>